package com.bb.flow.parser.impl.parsejson.parsenode.nodeimp;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bb.flow.api.exception.ParseException;
import com.bb.flow.config.AbstractConfigNode;
import com.bb.flow.config.enumtype.ExecuteType;
import com.bb.flow.config.node.ContainerConfigNode;
import com.bb.flow.config.node.ContainerInnerNode;

import static com.bb.flow.util.Tools.isEmptyOrNull;

/**
 * @author bigbeard
 * 解析容器类型的节点
 */
public class ParseContainerNode extends AbstractNodeImp {

    @Override
    public AbstractConfigNode parse(JSONObject jsonObject, String flowTemplateName, String parentNodeKey) throws ParseException {
        ContainerConfigNode containerConfigNode = new ContainerConfigNode();
        boolean b = parseNodeBaseInfo.parseNodeBaseInfo(containerConfigNode, jsonObject, flowTemplateName);
        if (!b) {
            return null;
        }
        String nodeKey = getNodeKey(parentNodeKey, containerConfigNode);

        String executeType = jsonObject.getString("ExecuteType");
        if (isEmptyOrNull(executeType)) {
            logger.warn("流程模版[{}]中的节点[{}]执行方式未配置,系统将采用默认的并行执行[PARALLEL_EXECUTE]", flowTemplateName, nodeKey);
            containerConfigNode.setExecuteType(ExecuteType.PARALLEL_EXECUTE);
        } else {
            executeType = executeType.toUpperCase();
            if (executeType.equals(ExecuteType.PARALLEL_EXECUTE.toString())) {
                containerConfigNode.setExecuteType(ExecuteType.PARALLEL_EXECUTE);
            } else if (executeType.equals(ExecuteType.SEQUENTIAL_EXECUTE.toString())) {
                containerConfigNode.setExecuteType(ExecuteType.SEQUENTIAL_EXECUTE);
            } else {
                logger.warn("流程模版[{}]中的节点[{}]执行方式配置错误,系统将采用默认的并行执行[PARALLEL_EXECUTE]", flowTemplateName, nodeKey);
                containerConfigNode.setExecuteType(ExecuteType.PARALLEL_EXECUTE);
            }
        }
        JSONArray nodes = jsonObject.getJSONArray("Nodes");
        if (null == nodes || nodes.isEmpty()) {
            String s = String.format("流程模版[%s]中的容器节点[%s]的内容为空", flowTemplateName, nodeKey);
            throw new ParseException(s);
        }
        for (int i = 0; i < nodes.size(); i++) {
            ContainerInnerNode containerInnerNode = parseInnerNode(nodes.getJSONObject(i), nodeKey, flowTemplateName);
            if (null != containerInnerNode) {
                containerConfigNode.addNode(containerInnerNode);
            }
        }
        return containerConfigNode;
    }

    private ContainerInnerNode parseInnerNode(JSONObject jsonObject, String nodeName, String flowTemplateName) throws ParseException {
        if (null == jsonObject) {
            String s = String.format("流程模版[%s]中的容器节点[%s]中的内容为null或者空", flowTemplateName, nodeName);
            throw new ParseException(s);
        }
        ContainerInnerNode containerInnerNode = new ContainerInnerNode();
        String nodeOrder = jsonObject.getString("NodeOrder");
        try {
            int i = Integer.parseInt(nodeOrder);
            containerInnerNode.setOrderIndex(i);
        } catch (Exception ex) {
            String s = String.format("流程模版[%s]中的容器节点[%s]中节点顺序[NodeOrder]属性配置错误,只能是英文状态的数字",
                    flowTemplateName, nodeName);
            throw new ParseException(s);
        }
        JSONArray flowNode = jsonObject.getJSONArray("FlowNode");
        for (int i = 0; i < flowNode.size(); i++) {
            JSONObject jsonObject1 = flowNode.getJSONObject(i);
            AbstractConfigNode configNode = nodeDispatcher.dispatcherParseNode(jsonObject1, nodeName, flowTemplateName);
            if (null != configNode) {
                containerInnerNode.addNode(configNode);
            }
        }
        return containerInnerNode;
    }
}
